home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / pacland.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  11KB  |  419 lines

  1. #include "driver.h"
  2. #include "vidhrdw/generic.h"
  3.  
  4.  
  5. static struct osd_bitmap *tmpbitmap2,*tmpbitmap3;
  6. static int scroll0,scroll1;
  7. static int palette_bank;
  8. static const unsigned char *pacland_color_prom;
  9.  
  10. static struct rectangle spritevisiblearea =
  11. {
  12.     3*8, 39*8-1,
  13.     5*8, 29*8-1
  14. };
  15.  
  16.  
  17. /***************************************************************************
  18.  
  19.   Convert the color PROMs into a more useable format.
  20.  
  21.   Pacland has one 1024x8 and one 1024x4 palette PROM; and three 1024x8 lookup
  22.   table PROMs (sprites, bg tiles, fg tiles).
  23.   The palette has 1024 colors, but it is bank switched (4 banks) and only 256
  24.   colors are visible at a time. So, instead of creating a static palette, we
  25.   modify it when the bank switching takes place.
  26.   The color PROMs are connected to the RGB output this way:
  27.  
  28.   bit 7 -- 220 ohm resistor  -- GREEN
  29.         -- 470 ohm resistor  -- GREEN
  30.         -- 1  kohm resistor  -- GREEN
  31.         -- 2.2kohm resistor  -- GREEN
  32.         -- 220 ohm resistor  -- RED
  33.         -- 470 ohm resistor  -- RED
  34.         -- 1  kohm resistor  -- RED
  35.   bit 0 -- 2.2kohm resistor  -- RED
  36.  
  37.   bit 3 -- 220 ohm resistor  -- BLUE
  38.         -- 470 ohm resistor  -- BLUE
  39.         -- 1  kohm resistor  -- BLUE
  40.   bit 0 -- 2.2kohm resistor  -- BLUE
  41.  
  42. ***************************************************************************/
  43. void pacland_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  44. {
  45.     int i;
  46.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  47.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  48.  
  49.  
  50.     pacland_color_prom = color_prom;    /* we'll need this later */
  51.     /* skip the palette data, it will be initialized later */
  52.     color_prom += 2 * 1024;
  53.     /* color_prom now points to the beginning of the lookup table */
  54.  
  55.     /* Sprites */
  56.     for (i = 0;i < TOTAL_COLORS(2)/3;i++)
  57.     {
  58.         COLOR(2,i) = *(color_prom++);
  59.  
  60.         /* color 0x7f is special, it makes the foreground tiles it overlaps */
  61.         /* transparent (used in round 19) */
  62.         if (COLOR(2,i) == 0x7f) COLOR(2,i + 2*TOTAL_COLORS(2)/3) = COLOR(2,i);
  63.         else COLOR(2,i + 2*TOTAL_COLORS(2)/3) = 0xff;
  64.  
  65.         /* transparent colors are 0x7f and 0xff - map all to 0xff */
  66.         if (COLOR(2,i) == 0x7f) COLOR(2,i) = 0xff;
  67.  
  68.         /* high priority colors which appear over the foreground even when */
  69.         /* the foreground has priority over sprites */
  70.         if (COLOR(2,i) >= 0xf0) COLOR(2,i + TOTAL_COLORS(2)/3) = COLOR(2,i);
  71.         else COLOR(2,i + TOTAL_COLORS(2)/3) = 0xff;
  72.     }
  73.  
  74.     /* Foreground */
  75.     for (i = 0;i < TOTAL_COLORS(0);i++)
  76.     {
  77.         COLOR(0,i) = *(color_prom++);
  78.         /* transparent colors are 0x7f and 0xff - map all to 0xff */
  79.         if (COLOR(0,i) == 0x7f) COLOR(0,i) = 0xff;
  80.     }
  81.  
  82.     /* Background */
  83.     for (i = 0;i < TOTAL_COLORS(1);i++)
  84.     {
  85.         COLOR(1,i) = *(color_prom++);
  86.     }
  87.  
  88.     /* Intialize transparency */
  89.     if (palette_used_colors)
  90.     {
  91.         memset (palette_used_colors, PALETTE_COLOR_USED, Machine->drv->total_colors * sizeof (unsigned char));
  92.         palette_used_colors[0xff] = PALETTE_COLOR_TRANSPARENT;
  93.     }
  94. }
  95.  
  96.  
  97.  
  98. int pacland_vh_start( void )
  99. {
  100.     if ( ( dirtybuffer = malloc( videoram_size ) ) == 0)
  101.         return 1;
  102.     memset (dirtybuffer, 1, videoram_size);
  103.  
  104.     if ( ( tmpbitmap = osd_create_bitmap( 64*8, 32*8 ) ) == 0 )
  105.     {
  106.         free( dirtybuffer );
  107.         return 1;
  108.     }
  109.  
  110.     if ( ( tmpbitmap2 = osd_create_bitmap( 64*8, 32*8 ) ) == 0 )
  111.     {
  112.         osd_free_bitmap(tmpbitmap);
  113.         free( dirtybuffer );
  114.         return 1;
  115.     }
  116.  
  117.     if ( ( tmpbitmap3 = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height) ) == 0 )
  118.     {
  119.         osd_free_bitmap(tmpbitmap2);
  120.         osd_free_bitmap(tmpbitmap);
  121.         free( dirtybuffer );
  122.         return 1;
  123.     }
  124.  
  125.     palette_bank = -1;
  126.  
  127.     return 0;
  128. }
  129.  
  130. void pacland_vh_stop(void)
  131. {
  132.     osd_free_bitmap(tmpbitmap3);
  133.     osd_free_bitmap(tmpbitmap2);
  134.     osd_free_bitmap(tmpbitmap);
  135.     free( dirtybuffer );
  136. }
  137.  
  138.  
  139.  
  140.  
  141. WRITE_HANDLER( pacland_scroll0_w )
  142. {
  143.     scroll0 = data + 256 * offset;
  144. }
  145.  
  146. WRITE_HANDLER( pacland_scroll1_w )
  147. {
  148.     scroll1 = data + 256 * offset;
  149. }
  150.  
  151.  
  152.  
  153. WRITE_HANDLER( pacland_bankswitch_w )
  154. {
  155.     int bankaddress;
  156.     unsigned char *RAM = memory_region(REGION_CPU1);
  157.  
  158.  
  159.     bankaddress = 0x10000 + ((data & 0x07) << 13);
  160.     cpu_setbank(1,&RAM[bankaddress]);
  161.  
  162. //    pbc = data & 0x20;
  163.  
  164.     if (palette_bank != ((data & 0x18) >> 3))
  165.     {
  166.         int i;
  167.         const unsigned char *color_prom;
  168.  
  169.         palette_bank = (data & 0x18) >> 3;
  170.         color_prom = pacland_color_prom + 256 * palette_bank;
  171.  
  172.         for (i = 0;i < 256;i++)
  173.         {
  174.             int bit0,bit1,bit2,bit3;
  175.             int r,g,b;
  176.  
  177.             bit0 = (color_prom[0] >> 0) & 0x01;
  178.             bit1 = (color_prom[0] >> 1) & 0x01;
  179.             bit2 = (color_prom[0] >> 2) & 0x01;
  180.             bit3 = (color_prom[0] >> 3) & 0x01;
  181.             r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  182.             bit0 = (color_prom[0] >> 4) & 0x01;
  183.             bit1 = (color_prom[0] >> 5) & 0x01;
  184.             bit2 = (color_prom[0] >> 6) & 0x01;
  185.             bit3 = (color_prom[0] >> 7) & 0x01;
  186.             g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  187.             bit0 = (color_prom[1024] >> 0) & 0x01;
  188.             bit1 = (color_prom[1024] >> 1) & 0x01;
  189.             bit2 = (color_prom[1024] >> 2) & 0x01;
  190.             bit3 = (color_prom[1024] >> 3) & 0x01;
  191.             b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  192.  
  193.             color_prom++;
  194.  
  195.             palette_change_color(i,r,g,b);
  196.         }
  197.     }
  198.     palette_change_color(0x7f,8,8,8);    /* make color 0x7f unique so we can use it for transparency */
  199. }
  200.  
  201.  
  202.  
  203. #define DRAW_SPRITE( code, sx, sy ) \
  204.         { drawgfx( bitmap, Machine->gfx[ 2+gfx ], code, color, flipx, flipy, sx, sy, \
  205.         &spritevisiblearea, TRANSPARENCY_COLOR,0xff); }
  206.  
  207. static void pacland_draw_sprites( struct osd_bitmap *bitmap,int priority)
  208. {
  209.     int offs;
  210.  
  211.     for (offs = 0;offs < spriteram_size;offs += 2)
  212.     {
  213.         int sprite = spriteram[offs];
  214.         int gfx = ( spriteram_3[offs] >> 7 ) & 1;
  215.         int color = ( spriteram[offs+1] & 0x3f ) + 64 * priority;
  216.         int x = (spriteram_2[offs+1]) + 0x100*(spriteram_3[offs+1] & 1) - 48;
  217.         int y = 256 - spriteram_2[offs] - 23;
  218.         int flipy = spriteram_3[offs] & 2;
  219.         int flipx = spriteram_3[offs] & 1;
  220.  
  221.         switch ( spriteram_3[offs] & 0x0c )
  222.         {
  223.             case 0:        /* normal size */
  224.                 DRAW_SPRITE( sprite, x, y )
  225.             break;
  226.  
  227.             case 4:        /* 2x horizontal */
  228.                 sprite &= ~1;
  229.                 if (!flipx)
  230.                 {
  231.                     DRAW_SPRITE( sprite, x, y )
  232.                     DRAW_SPRITE( 1+sprite, x+16, y )
  233.                 } else {
  234.                     DRAW_SPRITE( 1+sprite, x, y )
  235.                     DRAW_SPRITE( sprite, x+16, y )
  236.                 }
  237.             break;
  238.  
  239.             case 8:        /* 2x vertical */
  240.                 sprite &= ~2;
  241.                 if (!flipy)
  242.                 {
  243.                     DRAW_SPRITE( sprite, x, y-16 )
  244.                     DRAW_SPRITE( 2+sprite, x, y )
  245.                 } else {
  246.                     DRAW_SPRITE( 2+sprite, x, y-16 )
  247.                     DRAW_SPRITE( sprite, x, y )
  248.                 }
  249.             break;
  250.  
  251.             case 12:        /* 2x both ways */
  252.                 sprite &= ~3;
  253.                 if ( !flipy && !flipx )
  254.                 {
  255.                     DRAW_SPRITE( sprite, x, y-16 )
  256.                     DRAW_SPRITE( 1+sprite, x+16, y-16 )
  257.                     DRAW_SPRITE( 2+sprite, x, y )
  258.                     DRAW_SPRITE( 3+sprite, x+16, y )
  259.                 } else if ( flipy && flipx ) {
  260.                     DRAW_SPRITE( 3+sprite, x, y-16 )
  261.                     DRAW_SPRITE( 2+sprite, x+16, y-16 )
  262.                     DRAW_SPRITE( 1+sprite, x, y )
  263.                     DRAW_SPRITE( sprite, x+16, y )
  264.                 } else if ( flipx ) {
  265.                     DRAW_SPRITE( 1+sprite, x, y-16 )
  266.                     DRAW_SPRITE( sprite, x+16, y-16 )
  267.                     DRAW_SPRITE( 3+sprite, x, y )
  268.                     DRAW_SPRITE( 2+sprite, x+16, y )
  269.                 } else /* flipy */ {
  270.                     DRAW_SPRITE( 2+sprite, x, y-16 )
  271.                     DRAW_SPRITE( 3+sprite, x+16, y-16 )
  272.                     DRAW_SPRITE( sprite, x, y )
  273.                     DRAW_SPRITE( 1+sprite, x+16, y )
  274.                 }
  275.                 break;
  276.         }
  277.     }
  278. }
  279.  
  280.  
  281.  
  282. void pacland_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  283. {
  284.     int offs;
  285.     int sx,sy, code, flipx, flipy, color;
  286.  
  287.  
  288.     /* recalc the palette if necessary */
  289.     if (palette_recalc ())
  290.         memset (dirtybuffer, 1, videoram_size);
  291.  
  292.  
  293.     /* for every character in the Video RAM, check if it has been modified */
  294.     /* since last time and update it accordingly. */
  295.     for ( offs = videoram_size / 2; offs < videoram_size; offs += 2 )
  296.     {
  297.         if ( dirtybuffer[offs] || dirtybuffer[offs+1] )
  298.         {
  299.             dirtybuffer[offs] = dirtybuffer[offs+1] = 0;
  300.  
  301.             sx = ( ( ( offs - ( videoram_size / 2 ) ) % 128 ) / 2 );
  302.             sy = ( ( ( offs - ( videoram_size / 2 ) ) / 128 ) );
  303.  
  304.             flipx = videoram[offs+1] & 0x40;
  305.             flipy = videoram[offs+1] & 0x80;
  306.  
  307.             code = videoram[offs] + ((videoram[offs+1] & 0x01) << 8);
  308.             color = ((videoram[offs+1] & 0x3e) >> 1) + ((code & 0x1c0) >> 1);
  309.  
  310.             drawgfx(tmpbitmap,Machine->gfx[1],
  311.                     code,
  312.                     color,
  313.                     flipx,flipy,
  314.                     sx*8,sy*8,
  315.                     0,TRANSPARENCY_NONE,0);
  316.         }
  317.     }
  318.  
  319.     /* copy scrolled contents */
  320.     {
  321.         int i,scroll[32];
  322.  
  323.         /* x position is adjusted to make the end of level door border aligned */
  324.         for ( i = 0; i < 32; i++ )
  325.         {
  326.             if ( i < 5 || i > 28 )
  327.                 scroll[i] = 2;
  328.             else
  329.                 scroll[i] = -scroll1+2;
  330.         }
  331.  
  332.         copyscrollbitmap( bitmap, tmpbitmap, 32, scroll, 0, 0, &Machine->drv->visible_area, TRANSPARENCY_NONE, 0 );
  333.     }
  334.  
  335.     /* for every character in the Video RAM, check if it has been modified */
  336.     /* since last time and update it accordingly. */
  337.     for ( offs = 0; offs < videoram_size / 2; offs += 2 )
  338.     {
  339.         if ( dirtybuffer[offs] || dirtybuffer[offs+1] )
  340.         {
  341.             dirtybuffer[offs] = dirtybuffer[offs+1] = 0;
  342.  
  343.             sx = ( ( offs % 128 ) / 2 );
  344.             sy = ( ( offs / 128 ) );
  345.  
  346.             flipx = videoram[offs+1] & 0x40;
  347.             flipy = videoram[offs+1] & 0x80;
  348.  
  349.             code = videoram[offs] + ((videoram[offs+1] & 0x01) << 8);
  350.             color = ((videoram[offs+1] & 0x1e) >> 1) + ((code & 0x1e0) >> 1);
  351.  
  352.             drawgfx(tmpbitmap2,Machine->gfx[0],
  353.                     code,
  354.                     color,
  355.                     flipx,flipy,
  356.                     sx*8,sy*8,
  357.                     0,TRANSPARENCY_NONE,0);
  358.         }
  359.     }
  360.  
  361.     /* copy scrolled contents */
  362.     fillbitmap(tmpbitmap3,Machine->pens[0x7f],&Machine->drv->visible_area);
  363.     {
  364.         int i,scroll[32];
  365.  
  366.         for ( i = 0; i < 32; i++ )
  367.         {
  368.             if ( i < 5 || i > 28 )
  369.                 scroll[i] = 0;
  370.             else
  371.                 scroll[i] = -scroll0;
  372.         }
  373.  
  374.         copyscrollbitmap( tmpbitmap3, tmpbitmap2, 32, scroll, 0, 0, &Machine->drv->visible_area, TRANSPARENCY_COLOR, 0xff );
  375.     }
  376.     pacland_draw_sprites(tmpbitmap3,2);
  377.     copybitmap(bitmap,tmpbitmap3,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_COLOR,0x7f);
  378.  
  379.     pacland_draw_sprites(bitmap,0);
  380.  
  381.     /* redraw the tiles which have priority over the sprites */
  382.     fillbitmap(tmpbitmap3,Machine->pens[0x7f],&Machine->drv->visible_area);
  383.     for ( offs = 0; offs < videoram_size / 2; offs += 2 )
  384.     {
  385.         if (videoram[offs+1] & 0x20)
  386.         {
  387.             int scroll;
  388.  
  389.  
  390.             sx = ( ( offs % 128 ) / 2 );
  391.             sy = ( ( offs / 128 ) );
  392.  
  393.             if ( sy < 5 || sy > 28 )
  394.                 scroll = 0;
  395.             else
  396.                 scroll = -scroll0;
  397.  
  398.             if (sx*8 + scroll < -8) scroll += 512;
  399.  
  400.             flipx = videoram[offs+1] & 0x40;
  401.             flipy = videoram[offs+1] & 0x80;
  402.  
  403.             code = videoram[offs] + ((videoram[offs+1] & 0x01) << 8);
  404.             color = ((videoram[offs+1] & 0x1e) >> 1) + ((code & 0x1e0) >> 1);
  405.  
  406.             drawgfx(tmpbitmap3,Machine->gfx[0],
  407.                     code,
  408.                     color,
  409.                     flipx,flipy,
  410.                     sx*8 + scroll,sy*8,
  411.                     &Machine->drv->visible_area,TRANSPARENCY_COLOR,0xff);
  412.         }
  413.     }
  414.     pacland_draw_sprites(tmpbitmap3,2);
  415.     copybitmap(bitmap,tmpbitmap3,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_COLOR,0x7f);
  416.  
  417.     pacland_draw_sprites(bitmap,1);
  418. }
  419.